﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using DriveBeamEditor.Controls.BeamNG.VehiclePartConfig;
using JBeamLibrary.Tools;
using JBeamLibrary.Types;
using JBeamLibrary.VehicleParts.Elements;

namespace DriveBeamEditor.Controls.BeamNG.SectionControls
{
    public partial class GlowMapControl : VehiclePartControl
    {
        #region Properties

        private IEnumerable<GlobalGlowMaterial> SimpleMaterials
        {
            get
            {
                return VehiclePart != null
                    ? VehiclePart.GlowMap.OfType<GlobalGlowMaterial>()
                    : new GlobalGlowMaterial[0].AsEnumerable();
            }
        }

        private IEnumerable<CustomGlowMaterial> ExtendedMaterials
        {
            get
            {
                return VehiclePart != null
                    ? VehiclePart.GlowMap.OfType<CustomGlowMaterial>()
                    : new CustomGlowMaterial[0].AsEnumerable();
            }
        }

        private GlobalGlowMaterial CurrentSimpleMaterial
        {
            get { return simpleMatBindingSource.Current as GlobalGlowMaterial; }
        }

        private CustomGlowMaterial CurrentExtendedMaterial
        {
            get { return extendedMatBindingSource.Current as CustomGlowMaterial; }
        }

        #endregion

        #region CTORs

        public GlowMapControl()
        {
            InitializeComponent();
        }

        #endregion

        #region Events

        #region Binding sources

        private void simpleMatBindingSource_AddingNew(object sender, AddingNewEventArgs e)
        {
            if (DesignMode || VehiclePart == null)
            {
                e.NewObject = new GlobalGlowMaterial();
                return;
            }

            /* Avoid loop */
            if (e.NewObject is GlobalGlowMaterial) return;

            /* Create a new material */
            e.NewObject = new GlobalGlowMaterial(
                string.Format("{0}_{1}", VehiclePart.File.Parent.Name, Randomizer.GetRandomName()),
                string.Format("{0}_gauges_on", VehiclePart.File.Parent.Name),
                "invis",
                "running"
            );
        }

        private void simpleMatBindingSource_CurrentChanged(object sender, EventArgs e)
        {

        }

        private void extendedMatBindingSource_AddingNew(object sender, AddingNewEventArgs e)
        {
            if (DesignMode || VehiclePart == null)
            {
                e.NewObject = new CustomGlowMaterial();
                return;
            }

            /* Avoid loop */
            if (e.NewObject is CustomGlowMaterial) return;

            /* Create a new material */
            e.NewObject = new CustomGlowMaterial(
                string.Format("{0}_{1}", VehiclePart.File.Parent.Name, Randomizer.GetRandomName()),
                string.Format("{0}_lights_on", VehiclePart.File.Parent.Name),
                string.Format("{0}_lights", VehiclePart.File.Parent.Name),
                string.Format("{0}_lights_on_intense", VehiclePart.File.Parent.Name)
            );
        }

        private void extendedMatBindingSource_CurrentChanged(object sender, EventArgs e)
        {
            BindFunctions();
        }

        private void functionMapBindingSource_AddingNew(object sender, AddingNewEventArgs e)
        {
            if (DesignMode || VehiclePart == null)
            {
                e.NewObject = new GlowFunctionValue();
                return;
            }

            /* Avoid loop */
            if (e.NewObject is GlowFunctionValue) return;

            /* Create a new material */
            e.NewObject = new GlowFunctionValue(Randomizer.GetRandomName(), 0.3f);
        }

        private void functionMapBindingSource_CurrentChanged(object sender, EventArgs e)
        {

        }

        #endregion

        #region Data grid views

        private void gridSimpleMat_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            /* Clicks on headers */
            if (e.ColumnIndex < 0 || e.RowIndex < 0) return;
        }

        private void gridSimpleMat_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            /* Clicks on headers */
            if (e.ColumnIndex < 0 || e.RowIndex < 0) return;

            /* Get column & row & cell */
            var col = gridSimpleMat.Columns[e.ColumnIndex];
            var row = gridSimpleMat.Rows[e.RowIndex];

            /* Validate new row */
            if (row.IsNewRow && col == columnDeleteSimpleMat)
            {
                simpleMatBindingSource.EndEdit();
                gridSimpleMat.NotifyCurrentCellDirty(true);
                gridSimpleMat.EndEdit();
                gridSimpleMat.NotifyCurrentCellDirty(false);
            }

            /* Delete the current row */
            else if (col == columnDeleteSimpleMat && CurrentSimpleMaterial != null)
            {
                VehiclePart.GlowMap.Remove(CurrentSimpleMaterial);
                BindSimpleMaterials();
            }
        }

        private void gridExtendedMat_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            /* Clicks on headers */
            if (e.ColumnIndex < 0 || e.RowIndex < 0) return;
        }

        private void gridExtendedMat_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            /* Clicks on headers */
            if (e.ColumnIndex < 0 || e.RowIndex < 0) return;

            /* Get column & row & cell */
            var col = gridExtendedMat.Columns[e.ColumnIndex];
            var row = gridExtendedMat.Rows[e.RowIndex];

            /* Validate new row */
            if (row.IsNewRow && col == columnDeleteExtendedMat)
            {
                extendedMatBindingSource.EndEdit();
                gridExtendedMat.NotifyCurrentCellDirty(true);
                gridExtendedMat.EndEdit();
                gridExtendedMat.NotifyCurrentCellDirty(false);
            }

            /* Delete the current row */
            else if (col == columnDeleteExtendedMat && CurrentExtendedMaterial != null)
            {
                VehiclePart.GlowMap.Remove(CurrentExtendedMaterial);
                BindExtendedMaterials();
            }
        }

        private void gridFunctionMap_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            /* Clicks on headers */
            if (e.ColumnIndex < 0 || e.RowIndex < 0) return;
        }

        private void gridFunctionMap_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            /* Clicks on headers */
            if (e.ColumnIndex < 0 || e.RowIndex < 0) return;

            /* Get column & row & cell */
            var col = gridFunctionMap.Columns[e.ColumnIndex];
            var row = gridFunctionMap.Rows[e.RowIndex];

            /* Validate new row */
            if (row.IsNewRow && col == columnDeleteFunction)
            {
                functionMapBindingSource.EndEdit();
                gridFunctionMap.NotifyCurrentCellDirty(true);
                gridFunctionMap.EndEdit();
                gridFunctionMap.NotifyCurrentCellDirty(false);
            }

            /* Delete the current row */
            else if (col == columnDeleteFunction)
            {
                gridFunctionMap.Rows.RemoveAt(e.RowIndex);
            }
        }

        #endregion

        #region Buttons

        private void xbAddNewSimpleMat_Click(object sender, EventArgs e)
        {
            if (VehiclePart == null) return;

            VehiclePart.GlowMap.Add(new GlobalGlowMaterial(
                string.Format("{0}_{1}", VehiclePart.File.Parent.Name, Randomizer.GetRandomName()),
                string.Format("{0}_gauges_on", VehiclePart.File.Parent.Name),
                string.Format("{0}_gauges", VehiclePart.File.Parent.Name),
                "running"
            ));
            BindSimpleMaterials();
        }

        private void xbAddNewExtendedMat_Click(object sender, EventArgs e)
        {
            if (VehiclePart == null) return;

            VehiclePart.GlowMap.Add(new CustomGlowMaterial(
                string.Format("{0}_{1}", VehiclePart.File.Parent.Name, Randomizer.GetRandomName()),
                string.Format("{0}_lights_on", VehiclePart.File.Parent.Name),
                string.Format("{0}_lights", VehiclePart.File.Parent.Name),
                string.Format("{0}_lights_on_intense", VehiclePart.File.Parent.Name)
            ));
            BindExtendedMaterials();
        }

        #endregion

        #endregion

        #region Methods

        public override string ToString()
        {
            return "Glow map";
        }

        private void BindSimpleMaterials()
        {
            gridSimpleMat.Enabled = false;
            simpleMatBindingSource.DataSource = null;

            if (VehiclePart != null)
                simpleMatBindingSource.DataSource = SimpleMaterials;

            gridSimpleMat.Refresh();
            gridSimpleMat.Enabled = true;
        }

        private void BindExtendedMaterials()
        {
            gridExtendedMat.Enabled = false;
            extendedMatBindingSource.DataSource = null;

            if (VehiclePart != null)
                extendedMatBindingSource.DataSource = ExtendedMaterials;

            gridExtendedMat.Refresh();
            gridExtendedMat.Enabled = true;
        }

        private void BindFunctions()
        {
            gridFunctionMap.Enabled = false;
            functionMapBindingSource.DataSource = null;

            if (VehiclePart != null && CurrentExtendedMaterial != null)
                functionMapBindingSource.DataSource = CurrentExtendedMaterial.SimpleFunction;

            gridFunctionMap.Refresh();
            gridFunctionMap.Enabled = true;
        }

        protected override void OnVehiclePartChanged()
        {
            BindSimpleMaterials();
            BindExtendedMaterials();
            base.OnVehiclePartChanged();
        }

        #endregion
    }
}
